# coding: utf-8
"""
UCloud resources
============
"""
import json
import logging, commands
import thread
import traceback

import os
import re
import requests
from flask_marshmallow import base_fields
from flask_restplus import Resource, fields
from pexpect import run

import app
from app.extensions import db, log
from app.extensions.api import Namespace, abort, http_exceptions
from app.modules.apps.container import ContainerApp
from app.modules.apps.pipelines import ContainerAppPipeline, set_app_runtime_info, init_app_piplelines, \
    app_initializer
from app.modules.common.pipelines import PipelineNotFoundError
from app.modules.common.port import protected_port_group_pool
from config import BeetleConfig
from flask.ext.restplus_patched import Parameters

from datetime import datetime
from sqlalchemy import or_, and_
from app.modules.zones.models import Zone

# log = logging.getLogger()  # pylint: disable=invalid-name
api = Namespace('apps', description = "apps")  # pylint: disable=invalid-name

from . import parameters, schemas
from .models import App
from app.modules.common import pipeline_manager

api = Namespace('apps', description = "The interface for pipelines operation.")

pipeline_schema = api.model('App', {
    'name': fields.String(required = True, description = 'The pipeline name'),
    'group': fields.String(required = True, description = 'The pipeline group'),
    'status': fields.String(required = True, description = 'The pipeline status'),
    'pip': fields.Integer(required = True, description = 'The pipeline pip'),
    'progress': fields.Integer(required = True, description = 'The pipeline progress'),
    'lasted_started': fields.DateTime(required = True, description = 'The pipeline lasted_started'),
    'lasted_finished': fields.DateTime(required = True, description = 'The pipeline lasted_finished'),
})


@api.route('/')
class Apps(Resource):
    @api.parameters(parameters.AppsParameters())
    @api.response(schemas.BaseAppsSchema(many = True))
    def get(self, args):
        """
        List of teams.

        Returns a list of teams starting from ``offset`` limited by ``limit``
        parameter.
        """
        _zone_code = args['zone_code']
        if _zone_code is None:
            _app_list = App.query.filter_by(disabled = 0).filter_by(disabled = False).order_by(App.on_beetle.desc(),
                                                                                               App.app_id.asc(),
                                                                                               App.starting_order.asc()).all()
        else:
            _app_list = App.query.filter_by(disabled = 0).filter_by(zone_code = _zone_code).filter_by(
                disabled = False).order_by(
                App.on_beetle.desc(), App.app_type,
                App.app_id.asc(), App.starting_order.asc())

        newapps = []
        for app in _app_list:
            set_app_runtime_info(app)

            newapps.append(app)

        return newapps


class StartPipelineParameters(Parameters):
    pipeline_name = base_fields.String(
        description = 'The name of pipeline will be start',
        required = True
    )
    params = base_fields.String(
        description = 'The parameters of pipeline will be start,must be json format.',
        required = False,
        missing = "{}"
    )


@api.route('/start')
@api.response(
    code = http_exceptions.NotFound.code,
    description = "pipeline not found.",
)
class StartContainerAppPipelineByName(Resource):
    """
    启动单个app初始化pipe的入口, 支持通过pipeline_name(可通过app_id加上install|stop|restart来生成).
    """

    @api.parameters(StartPipelineParameters())
    @api.marshal_with(pipeline_schema)
    def get(self, args):
        """
        Start a pipeline by name.
        """
        try:
            pipeline_name = args['pipeline_name']
            params = json.loads(args['params'])

            _path = params.get('package_path')
            _sub_path = params.get('sub_path')
            _version = params.get('version')

            msg = 'Starting pipeline, package_path=%s, sub_path=%s, version=%s' % (_path, _sub_path, _version)
            log.info(msg)

            pipeline = pipeline_manager.get_pipeline(pipeline_name)

            if not isinstance(pipeline, ContainerAppPipeline):
                raise BaseException('Only container app pipeline can be sepceific.')
            _app_id = getattr(pipeline, '_app_id')

            container_app = app.container_pool.get(_app_id)

            if not isinstance(container_app, ContainerApp):
                raise BaseException('Only container app pipeline can be sepceific.')

            _install_pipe = re.search("^[A-Za-z0-9]*:[A-Za-z0-9]*(-.*)*_(install)", pipeline_name, re.M)

            # container_app.set_runtime_param(_path, _version, _sub_path)

            # 只有安装应用有必要配置这个参数,其余piple无需指定运行时参数.
            if _install_pipe is not None:
                container_app.set_runtime_param(_path, _version, _sub_path)

            # 启动pipline,安装或重启应用.
            pipeline_manager.start_pipeline(pipeline_name = pipeline_name, pipeline_params = params)

            # 应用启动停止pipline，更新app字段
            _app = App.query.filter_by(app_id = _app_id).first()
            if _app is None:
                return None
            if '_restart' in pipeline_name or '_install' in pipeline_name:
                _app.app_start_date = datetime.now()
                db.session.commit()
            elif '_stop' in pipeline_name:
                _app.app_stop_date = datetime.now()
                db.session.commit()

        except PipelineNotFoundError:
            abort(code = http_exceptions.NotFound.code, message = "Could not found the pipeline:%s" % pipeline_name)
        except BaseException as e:
            log.error(e.message)
            abort(code = http_exceptions.NotFound.code, message = e.message)

        return None


class LockFreeAppPortsParameters(Parameters):
    app_id = base_fields.String(
        description = 'The app_id of ports which to be free or lock.',
        required = True
    )
    switch = base_fields.String(
        description = 'free|lock.',
        required = True,
        missing = "lock"
    )


port_free_lock_api = Namespace('port_free_lock', description = "The interface for pipelines operation.")

common_schema = port_free_lock_api.model('result', {
    'success': fields.Boolean(required = True, description = 'Is Lock/free operation successfully.'),
    'msg': fields.String(required = False, description = 'Error message when lock/free failed.')
})


@api.route('/lock_free_port')
@api.response(
    code = http_exceptions.NotFound.code,
    description = "pipeline not found.",
)
class LockFreeAppPortsByAppId(Resource):
    @api.parameters(LockFreeAppPortsParameters())
    @api.marshal_with(common_schema)
    def get(self, args):

        try:
            app_id = args['app_id']
            switch = args['switch']

            log.info("准备%s 应用%s: 的端口," % (switch, app_id))
            # _success = True
            if switch == 'lock':
                _success = protected_port_group_pool.protect_port_group(app_id)
            elif switch == 'free':
                _success = protected_port_group_pool.free_port_group(app_id)
            else:
                raise Exception('switch 只允许输入 lock和free两种参数')

            return {'success': _success}

        except BaseException, msg:

            return {'success': False, 'msg': msg}


@api.route('/app_init_status')
@api.response(
    code = http_exceptions.NotFound.code,
    description = "pipeline not found.",
)
class AppInitStatus(Resource):
    """
    获取App整体的初始化状态, 避免重复初始化

    """

    @api.marshal_with(common_schema)
    def get(self):

        try:

            return {'success': False, 'msg': app_initializer.status}

        except BaseException, msg:

            return {'success': False, 'msg': msg}


class InitZoneParameters(Parameters):
    zone_codes = base_fields.String(
        description = 'zone_codes split by comma.',
        required = False
    )


@api.route('/init')
class InitZoneApps(Resource):
    @api.parameters(InitZoneParameters())
    @api.marshal_with(common_schema)
    def get(self, args):

        if app_initializer.status == 'initializing':
            return {'success': True, 'msg': app_initializer.status}

        _success = False
        _msg = ''
        try:
            # 获取所有应用
            _zone_codes = args.get('zone_codes')

            _app_pkg_version = get_app_pkg_version()

            print "经过排重复, 一有%d 个应用版本信息" % len(_app_pkg_version)
            log.info(msg = "经过排重复, 一有%d 个应用版本信息" % len(_app_pkg_version))

            if _zone_codes is None:

                # 如果zone为空, 则获取所有zone.
                _apps = App.query.filter_by(disabled = 0).order_by(App.starting_order.asc()).all()
            else:
                _init_zone_codes = str(_zone_codes).split(',')
                _apps = App.query.filter_by(disabled = 0).filter(App.zone_code.in_(_init_zone_codes)).order_by(
                    App.starting_order.asc()).all()

            # 启动一个线程, 逐个安装所有应用的最新版本.
            print "一共有%d个应用需要安装." % len(_apps)
            log.info(msg = "一共有%d个应用需要安装." % len(_apps))

            app_initializer.do_init(_apps, _app_pkg_version)

            _success = True

        except:
            log.error(traceback.format_exc())
            abort(code = http_exceptions.NotFound.code, message = "Could not found the zone_code:%s" % _zone_codes)

        return {'success': _success, 'msg': _msg}


class StatusUpdateParameters(Parameters):
    app_id = base_fields.String(
        description = 'app_id.',
        required = True
    )

    version = base_fields.String(
        description = 'version of app.',
        required = False,
        missing = 'defalut'
    )
    status = base_fields.String(
        description = 'status of app.',
        required = False,
        missing = "ready"
    )

    last_msg = base_fields.String(
        description = 'last error message of app.',
        required = False,
        missing = ""
    )
    app_package_create_date = base_fields.String(
        description = 'app_package_create_date of app.',
        required = False,
        missing = ""
    )


@api.route('/status_update')
@api.response(
    code = http_exceptions.NotFound.code,
    description = "pipeline not found.",
)
class StatusUpdate(Resource):
    @api.parameters(StatusUpdateParameters())
    @api.marshal_with(common_schema)
    def get(self, args):

        try:

            _app_id = args['app_id']
            _status = args['status']
            _last_msg = args['last_msg']
            _app_package_create_date = args['app_package_create_date']
            _version = args['version']

            _app = App.query.filter_by(disabled = 0).filter_by(app_id = _app_id).first()

            if _app is None:
                return {'success': False, 'msg': 'Invalid app_id.'}

            _app.status = _status
            _app.last_msg = unicode(_last_msg)

            _app.app_package_create_date = _app_package_create_date
            _app.version = _version
            db.session.commit()

            return {'success': True}

        except BaseException, msg:

            logging.error(traceback.format_exc())

            traceback.print_exc()

            return {'success': False, 'msg': msg}


@api.route('/reflush_apps')
@api.response(
    code = http_exceptions.NotFound.code,
    description = "pipeline not found.",
)
class ReflushApps(Resource):
    @api.parameters(Parameters())
    @api.marshal_with(common_schema)
    def get(self, args):

        try:
            list = App.query.filter_by(disabled = 0).order_by(App.starting_order.asc()).all()

            init_app_piplelines(list)

            return {'success': True}

        except BaseException, msg:

            return {'success': False, 'msg': msg}


@api.route('/<string:app_id>/logs')
class AppRelease(Resource):
    # @api.resolve_object_by_model(App, 'app')
    @api.resolve_object(object_arg_name = 'app', resolver = lambda kwargs: App(app_id = kwargs.pop('app_id')))
    @api.parameters(parameters.AppsLoggingParameters())
    @api.response(code = http_exceptions.Conflict.code)
    def put(self, args, app):
        app_id = app.app_id
        log_type = args['log_type']
        log_lines = args['log_lines']
        log.info("============== start tail log ==============")
        log.info("============== param[app_id] is %s", app_id)
        log.info("============== param[log_type] is %s", log_type)
        log.info("============== param[log_lines] is %s", log_lines)

        if log_type not in ['app', 'pip-app', 'pip-db']:
            abort(508, 'Parameter error, log_type can be selected as [app, pip-app, pip-db]')

        new_app = App.query.filter_by(disabled = 0).filter_by(app_id = app_id).one()
        log.info("============== app is %s", app.__repr__())

        if not new_app:
            abort(509, 'Unable to query to app configuration information based on appi[%s]' % app_id)

        if log_type == 'pip-db':
            if new_app.db_name and new_app.db_type:
                log_file_path = '%s/%s_%s.log' % (BeetleConfig.PIPELINE_DB_LOG_PATH, new_app.db_type, new_app.db_name)
            else:
                return '没有指定数据库或与其他应用共享同一数据库'
        elif log_type == 'pip-app':
            log_file_path = '%s/%s.log' % (BeetleConfig.PIPELINE_APP_LOG_PATH, new_app.app_id)
        elif log_type == 'app':
            log_file_path = '%s/%s.log' % (BeetleConfig.APP_LOG_PATH, new_app.app_id)
        else:
            log_file_path = None

        if log_file_path and os.path.exists(log_file_path):
            return self.__tail_logs(log_lines, log_file_path)
        else:
            return '没有找到日志文件:%s' % log_file_path

    def __tail_logs(self, log_lines, file_name):
        sh = '/bin/bash -c "tail -n %s %s"' % (log_lines, file_name)
        log.info('=====> tail : %s', sh)
        output, status = run(sh, withexitstatus = 1, timeout = 30)
        if status != 0:
            log.info('=======> shell status: %s, output: %s', status, output)
        else:
            log.info('=======> shell status: %s', status)
            output = str(output)
            while output.find('\r\n\r\n') > 0:
                output = output.replace('\r\n\r\n', '\r\n')
            while output.find('\r\n') > 0:
                output = output.replace('\r\n', '<br>')

        return output


def get_app_pkg_version():
    """
    将app表中的所有应用对应的beetle版本, 包路径信息获取到.
    数据源是app表, 获取版本用的服务是beetle-api提供的.
    :return: 以app_name为key的字典信息,每条记录包括version package_path
    """

    # 1. 查询需要beetle提供版本信息的app记录(去掉重复记录).
    _apps = App.query.filter_by(disabled = 0).filter_by(on_beetle = 'true').group_by(App.app_name).order_by(
        App.starting_order.asc())
    _app_names = []

    # 2. 将app_id从查询结果中抽取出来, 拼接成逗号链接的字符串.
    for _app in _apps:
        _app_names.append(str(_app.app_name) + ',')

    _http_call_param_app_names = ''.join(_app_names)

    # 3.向BeetleApi发送请求, 查询各应用对应的版本号.
    s = requests.post(url = '%s/uCloud/getProjectVersions' % BeetleConfig.BEETLE_API_URL, data = {
        'apps': _http_call_param_app_names,
    }).content

    _app_pk_data = json.loads(s)['data']

    result_dict = {}

    # 4. 将或得到的数据从数组转化成字典的格式.
    for _app_pkg_version in _app_pk_data:

        _app_name = _app_pkg_version.get('app')

        if _app_name in result_dict:
            continue
        else:
            result_dict.setdefault(_app_name, _app_pkg_version)

    return result_dict


class UpdateCParameters(Parameters):
    zone_codes = base_fields.String(
        description = 'zone_codes split by comma.',
        required = False,
        missing = None
    )
    integration_name = base_fields.String(
        description = '集成计划名称，例如：集成计划2018第22周',
        required = True
    )


@api.route('/updateC')
class UpdateCApps(Resource):
    @api.parameters(UpdateCParameters())
    @api.marshal_with(common_schema)
    def get(self, args):
        """
        c环境初始化专用
        通过传入的集成计划周期和区域，自动获取到集成计划内应用对应的线上版本，并部署到传入的区域中
        :param args:
        :return:
        """
        if app_initializer.status == 'initializing':
            return {'success': True, 'msg': app_initializer.status}

        _success = False
        _msg = ''
        try:
            _zone_codes = args.get('zone_codes')
            _integration_name = args.get('integration_name')

            # 获取集成计划内要发版的应用
            s = requests.get(
                '%s/integration/getIntegrationProjectInfoList?token_id=1&isHideMergePro=true&integration_name=%s' % (
                    BeetleConfig.BEETLE_PLAN_URL, _integration_name)).content

            _integration_apps = json.loads(s)['data']
            _app_names = []
            _http_call_param_app_names = ''
            for app in _integration_apps:
                if app['isOnBeetle'] == '0':
                    log.info(msg = "更新集成计划应用。%s " % str(app['trunk_name']))
                    _app_names.append(str(app['trunk_name']))
                    _http_call_param_app_names = '%s%s,' % (_http_call_param_app_names, str(app['trunk_name']))

            # 获取应用对应的线上版本信息
            s = requests.post(url = '%s/uCloud/getProjectVersions' % BeetleConfig.BEETLE_API_URL, data = {
                'apps': _http_call_param_app_names,
            }).content

            _app_pk_data = json.loads(s)['data']

            result_dict = {}

            for _app_pkg_version in _app_pk_data:

                _app_name = _app_pkg_version.get('app')

                if _app_name in result_dict:
                    continue
                else:
                    result_dict.setdefault(_app_name, _app_pkg_version)
            log.info(msg = "经过排重复, 一有%d 个应用版本信息" % len(result_dict))

            # 根据zone查询应用列表
            if _zone_codes is None:
                # 如果zone为空, 则获取所有zone.
                _apps = App.query.filter_by(disabled = 0).filter(App.app_name.in_(_app_names)).order_by(
                    App.starting_order.asc()).all()
            else:
                _init_zone_codes = str(_zone_codes).split(',')
                _apps = App.query.filter_by(disabled = 0).filter(App.zone_code.in_(_init_zone_codes)).filter(
                    App.app_name.in_(_app_names)).order_by(App.starting_order.asc()).all()

            # 启动一个线程, 逐个安装所有应用的最新版本.
            log.info(msg = "一共有%d个应用需要安装." % len(_apps))
            app_initializer.do_init(_apps, result_dict)

            _success = True

        except:
            log.error(traceback.format_exc())
            abort(code = http_exceptions.NotFound.code, message = "Could not found the zone_code:%s" % _zone_codes)

        return {'success': _success, 'msg': _msg}


# 处理基础组件
def dealBaseApp(_app_pkg_version = None, zone_code = None, pip_type = None):
    # if _app_pkg_version is None:
    #     _app_pkg_version = get_app_pkg_version()

    _query = App.query
    if zone_code is not None:
        _query = _query.filter_by(zone_code = zone_code)
    _apps = _query.filter_by(disabled = 0).filter(App.starting_order <= 100).order_by(App.starting_order.asc()).all()
    for _app in _apps:
        log.info(msg = "安装基础组件 %s" % _app.app_id)
        dealApp(_app, _app_pkg_version, pip_type = pip_type)
    return None


# 部署启动应用
def dealApp(_app, _app_pkg_version = None, pip_type = None):
    log.info(msg = "部署应用 %s" % _app.app_id)
    if pip_type is None:
        log.error(msg = "部署应用 %s,pip_type 为none" % _app.app_id)
        return
    # 执行重启
    try:
        # 先安装，再重启
        container_app = app.container_pool.get(_app.app_id)
        if not isinstance(container_app, ContainerApp):
            raise BaseException(
                'Only container app pipeline can be sepceific.')

        pipeline_name = _app.app_id + '_' + pip_type
        if pip_type == 'install':
            if not _app.on_beetle == 'true':
                container_app.set_runtime_param('', '', None)
                pipeline_manager.start_pipeline(pipeline_name = pipeline_name)
            elif _app_pkg_version.has_key(str(_app.app_name)):
                _pkg_version = _app_pkg_version.get(_app.app_name)
                _path = _pkg_version.get('package_path')
                _version = _pkg_version.get('version')
                if os.path.isfile(_path):
                    _path = os.path.dirname(_path)
                container_app.set_runtime_param(_path, _version, None)
                pipeline_manager.start_pipeline(pipeline_name = pipeline_name)
            else:
                log.warn("部署应用异常。%s" % _app.app_id)
        elif pip_type == 'restart':
            pipeline_manager.start_pipeline(pipeline_name = pipeline_name)
    except PipelineNotFoundError:
        log.error(msg = "部署应用 %s 失败" % _app.app_id)
        abort(code = http_exceptions.NotFound.code, message = "Could not found the pipeline:%s" % pipeline_name)


# 启动基础应用
def dealDeptApp(_app_pkg_version = None, zone_code = None, pip_type = None):
    # if _app_pkg_version is None:
    #     _app_pkg_version = get_app_pkg_version()
    _query = App.query
    if zone_code is not None:
        _query = _query.filter_by(zone_code = zone_code)

    _apps = _query.filter_by(disabled = 0).filter(App.starting_order > 100).filter(
        App.starting_order <= 200).order_by(App.starting_order.asc()).all()

    for _app in _apps:
        log.info(msg = "启动基础应用 %s" % _app.app_id)
        dealApp(_app, _app_pkg_version, pip_type = pip_type)
    return None


#
# @api.route('/startBaseApp')
# class StartBaseApp(Resource):
#     @api.parameters(parameters.AppsParameters())
#     @api.marshal_with(common_schema)
#     def get(self, args):
#         """
#         启动基础组件
#         :param args:
#         :return:
#         """
#         _zone_code = args['zone_code']
#         log.info("start %s base apps " % _zone_code)
#         startBaseApp(zone_code = _zone_code)


@api.route('/recoverApps')
class recoverApps(Resource):
    @api.parameters(Parameters())
    @api.marshal_with(common_schema)
    def get(self, args):
        """
        停电恢复，启动停电前的应用
        :param args:
        :return:
        """
        log.info("start recover apps")

        # 停电恢复，启动所有区域下的应用
        _apps = App.query.filter_by(disabled = 0).filter(or_(App.app_start_date > App.app_stop_date,
                                                             and_(App.app_start_date != None,
                                                                  App.app_stop_date == None))).order_by(
            App.starting_order.asc()).all()
        for _app in _apps:
            log.info(msg = "启动应用 %s" % _app.app_id)
            try:
                dealApp(_app, None, pip_type = 'restart')
            except BaseException as e:
                log.error(traceback.format_exc())
                log.error("启动应用 %s 异常。%s" % (_app.app_id, e.message))
        return {'success': True, 'msg': ''}


@api.route('/startApps')
class startApps(Resource):
    @api.parameters(parameters.StartAppParameters())
    @api.marshal_with(common_schema)
    def get(self, args):
        """
        按区自动启动应用,默认启动中国区、深圳仓、美国区、美西仓
        :param args:
        :return:
        """
        _zone_code = args['zone_code']

        log.info("start %s apps " % _zone_code)

        for _zone in str(_zone_code).split(','):
            dealBaseApp(_app_pkg_version = None, zone_code = _zone, pip_type = 'restart')
            dealDeptApp(_app_pkg_version = None, zone_code = _zone, pip_type = 'restart')

            _apps = App.query.filter_by(disabled = 0).filter(App.starting_order > 200).filter(
                App.zone_code == _zone).order_by(App.starting_order.asc()).all()
            for _app in _apps:
                log.info(msg = "启动 %s 应用 %s" % (_zone, _app.app_id))
                dealApp(_app, None, 'restart')
        return {'success': True, 'msg': ''}


@api.route('/installApps')
class installApps(Resource):
    @api.parameters(parameters.InstallAppParameters())
    @api.marshal_with(common_schema)
    def get(self, args):
        """
        按区域部署应用，默认部署所有区域
        :param args:
        :return:
        """
        _zone_code = args['zone_code']
        log.info("start install %s apps " % _zone_code)

        _app_pkg_version = get_app_pkg_version()
        if _zone_code is None:
            for _zone in Zone.query.all():
                dealBaseApp(_app_pkg_version = _app_pkg_version, zone_code = _zone.zone_code, pip_type = 'install')
                dealDeptApp(_app_pkg_version = _app_pkg_version, zone_code = _zone.zone_code, pip_type = 'install')

                _apps = App.query.filter_by(disabled = 0).filter(App.starting_order > 200).filter(
                    App.zone_code == _zone.zone_code).order_by(App.starting_order.asc()).all()
                for _app in _apps:
                    log.info(msg = "启动 %s 应用 %s" % (_zone.zone_code, _app.app_id))
                    dealApp(_app, _app_pkg_version, pip_type = 'install')
        else:
            for _zone in str(_zone_code).split(','):
                dealBaseApp(_app_pkg_version = _app_pkg_version, zone_code = _zone, pip_type = 'install')
                dealDeptApp(_app_pkg_version = _app_pkg_version, zone_code = _zone, pip_type = 'install')

                _apps = App.query.filter_by(disabled = 0).filter(App.starting_order > 200).filter(
                    App.zone_code == _zone).order_by(App.starting_order.asc()).all()
                for _app in _apps:
                    log.info(msg = "启动 %s 应用 %s" % (_zone, _app.app_id))
                    dealApp(_app, _app_pkg_version, pip_type = 'install')
        return {'success': True, 'msg': ''}


_is_auto_running = False


@api.route('/doTest')
class DoTest(Resource):
    @api.parameters(parameters.AutoTestParameters())
    @api.marshal_with(common_schema)
    def get(self, args):
        """
        启动冒烟测试
        :param args:
        :return:
        """
        _account = args['account']

        # 获取本机ip并修改自动测试文件
        from app.modules.common.network import ip
        log.info('=== do auto test %s , ip is %s ===' % (_account, ip))

        global _is_auto_running
        if _is_auto_running:
            log.info('=== auto test is running ===')
            return {'success': True, 'msg': 'auto test is running'}

        _config_file_path = '/root/auto/Auto_Winit_Api_2.0/CustomLibrarys/AutoRunningConfig.txt'
        _contain = r'*** Variables ***' + '\n' \
                   + r'${running_machine}    ' + ip + '\n' \
                   + r'${running_user}    ' + _account + '\n' \
                   + r'${running_ukid}    20180709095850696000' + '\n'

        with open(_config_file_path, 'w') as _f:
            _f.write(_contain)

        _cmd = '/bin/bash -c "rm -rf /root/auto/log/*;mkdir -p /root/auto/log;nohup pybot -d /root/auto/log /root/auto/Auto_Winit_Api_2.0/1_Case/3_快速冒烟/快速冒烟.txt 2>&1 > /root/auto/log/runtime_log.html &"'

        try:
            rtn, status = run(_cmd, withexitstatus = 1, timeout = 3000)
            if status != 0:
                log.info('=======> run auto test . status is %s .rtn is %s ' % (status, rtn))
            else:
                if not str(rtn).__contains__('pybot'):
                    _is_auto_running = True
                log.info('=======> run auto test . status : 0 . rtn : %s' % rtn)
            # rtn = commands.getoutput(_cmd)
            return {'success': True, 'msg': rtn}
        except BaseException as e:
            log.error(traceback.format_exc())
            return {'success': True, 'msg': e.message}


@api.route('/testStatus')
class DestStatus(Resource):
    @api.parameters(Parameters())
    @api.marshal_with(common_schema)
    def get(self, args):
        """
        获取自动测试结果
        :param args:
        :return:
        """
        log.info('=== start check auto test status ===')
        log_path = '/root/auto/log/log.html'
        global _is_auto_running
        if not os.path.exists(log_path):
            log.info('=== not run auto test or no result ===')
            if _is_auto_running:
                return {'success': True, 'msg': 'running'}
            else:
                return {'success': True, 'msg': 'none'}

        _is_auto_running = False

        file_object = open(log_path, 'r')
        all_the_text = file_object.read()

        result = re.sub("([\\s\\S]*)(\\{)([\\S\\s]*)(All Tests)([\\s\\S]*?)(})([\\s\\S]*)", "\\2\\3\\4\\5\\6",
                        all_the_text)
        log.info('=== auto test result is %s ===' % result)
        if eval(result)['fail'] == 0:
            return {'success': True, 'msg': 'pass'}
        else:
            return {'success': True, 'msg': 'fail'}
